/*******************************************************************************
  * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
  * @file     curve.c
  * @author   UartTFT Application Team
  * @version  V0.0.1
  * @date     2023-01-04
  * @brief    This file contains the functions prototypes for the UartTFT
  *           Application display firmware.
 ********************************************************************************/
#include "curve.h"
#include "levetop.h"
#include "data.h"
#include "popupBox.h"



Curve_Info gCurve_Info[CURVE_SIZE];
uint16_t Curve_buff[CURVE_SIZE][1024] = {0}; // Curve data buffer: 8 channels, 16KB in total
uint16_t Curve_count[CURVE_SIZE] = {0};		// Curve length
uint8_t  curve_update_flag[CURVE_SIZE];		// Curve update flag

uint8_t curve_num = 0;		 // Number of curve controls
uint8_t curve_flag = 0;		 // Curve timing refresh flag bit
uint8_t curve_group_sum = 1; // Total number of groups in curve area

void Display_Curve(void)
{
    uint8_t i = 0, j = 0;
    if (curve_num && curve_flag)
    {
        curve_flag = 0;
        for (i = 1; i <= curve_group_sum; i++)
        {
            for (j = 0; j < curve_num; j++)
            {
                // When a channel data is updated, multiple controls in the same group will be updated accordingly
                if (curve_update_flag[gCurve_Info[j].channel] && gCurve_Info[j].group == i)
                {
                    Real_time_curve_display_dynamic(i);
                    break;
                }
            }
        }
        for (i = 0; i < CURVE_SIZE; i++) // After all the curves are updated, clear the flag
        {
            curve_update_flag[i] = 0;
        }
    }
}
/***********************************************************************************
 * Function Name : Real_time_curve_display_static
 * Description   : Show static curves.
 * Input         : - curve: curve info
 * Output        : None
 * Return        : None
 ************************************************************************************/
void Real_time_curve_display_static(Curve_Info curve)
{
    uint16_t points = 0, num = 0, yCentral = 0, x, y;
    int16_t X0 = 0, X1 = 0, Y0 = 0, Y1 = 0;
    uint16_t buff_w = curve.xe - curve.xs, buff_h = curve.ye - curve.ys;


  	if (Screen_DIR == 0)
	{
		if (curve.dir == 0)
		{
			x = curve.xe - (curve.Width - 1);
			points = (x - curve.xs + 1) / curve.Dis_HOR;
		}
		else
		{
			x = curve.xs;
			points = (curve.xe - x + 1) / curve.Dis_HOR;
		}
		yCentral = (curve.ys + curve.Y_Central) + curve.VD_Central * curve.MUL_Y / 256;
	}
	else if (Screen_DIR == 1)
	{
		if (curve.dir == 0)
		{
			y = curve.ye - (curve.Width - 1);
			points = (y - curve.ys + 1) / curve.Dis_HOR;
		}
		else
		{
			y = curve.ys;
			points = (curve.ye - y + 1) / curve.Dis_HOR;
		}
	}
	else if (Screen_DIR == 2)
	{
		if (curve.dir == 0)
		{
			x = curve.xs;
			points = (curve.xe - x - 1) / curve.Dis_HOR;
		}
		else
		{
			x = curve.xe - (curve.Width - 1);
			points = (x - curve.xs + 1) / curve.Dis_HOR;
		}
	}
	else if (Screen_DIR == 3)
	{
		if (curve.dir == 0)
		{
			y = curve.ys;
			points = (curve.ye - y + 1) / curve.Dis_HOR;
		}
		else
		{
			y = curve.ye - (curve.Width - 1);
			points = (y - curve.ys + 1) / curve.Dis_HOR;
		}
		yCentral = (curve.xs + curve.Y_Central) + curve.VD_Central * curve.MUL_Y / 256;
	}

    num = Curve_count[curve.channel] - 1 + 1024;

    // full-screen background
//    LT268_pic_to_buffer(0, 0, buff_w, m_PngData,
//                        curve.xs, curve.ys, LCD_XSIZE_TFT, FullScreen_addr,
//                        buff_w, buff_h, FullScreen_flag);
    if(pic_update == 0)
    	LT268_BG_to_buffer(0, 0, buff_w, m_PngData,curve.xs, curve.ys, buff_w, buff_h);

    for (uint16_t i = 0; i < points; i++)
    {
        if (Screen_DIR == 0)
		{
			X0 = x;
			if (curve.dir == 0)
			{
				X1 = x - curve.Dis_HOR;
				if (X1 < curve.xs)
					break;
			}
			else
			{
				X1 = x + curve.Dis_HOR;
				if (X1 + (curve.Width - 1) > curve.xe)
					break;
			}

			Y0 = yCentral - Curve_buff[curve.channel][num % 1024] * curve.MUL_Y / 256;
			Y1 = yCentral - Curve_buff[curve.channel][(num - 1) % 1024] * curve.MUL_Y / 256;

			if (Y0 < curve.ys)
				Y0 = curve.ys; // When the Y coordinate exceeds the upper or lower limit, it defaults to the upper or lower limit coordinate value
			else if (Y0 > curve.ye - curve.Width + 1)
				Y0 = curve.ye - curve.Width + 1; // Keep the part with lineweight greater than 1, so the Y coordinate value should be offset (lineweight - 1) pixels
			if (Y1 < curve.ys)
				Y1 = curve.ys;
			else if (Y1 > curve.ye - curve.Width + 1)
				Y1 = curve.ye - curve.Width + 1;
		}
		else if (Screen_DIR == 1)
		{
			Y0 = y;
			if (curve.dir == 0)
			{
				Y1 = y - curve.Dis_HOR;
				if (Y1 < curve.ys)
					break;
			}
			else
			{
				Y1 = y + curve.Dis_HOR;
				if (Y1 + (curve.Width - 1) > curve.ye)
					break;
			}

			X0 = (curve.xe - curve.Y_Central) + (Curve_buff[curve.channel][num % 1024] - curve.VD_Central) * curve.MUL_Y / 256;
			X1 = (curve.xe - curve.Y_Central) + (Curve_buff[curve.channel][(num - 1) % 1024] - curve.VD_Central) * curve.MUL_Y / 256;

			if (X0 < curve.xs)
				X0 = curve.xs;
			else if (X0 > curve.xe - curve.Width + 1)
				X0 = curve.xe - curve.Width + 1;
			if (X1 < curve.xs)
				X1 = curve.xs;
			else if (X1 > curve.xe - curve.Width + 1)
				X1 = curve.xe - curve.Width + 1;
		}
		else if (Screen_DIR == 2)
		{
			X0 = x;
			if (curve.dir == 0)
			{
				X1 = x + curve.Dis_HOR;
				if (X1 + (curve.Width - 1) > curve.xe)
					break;
			}
			else
			{
				X1 = x - curve.Dis_HOR;
				if (X1 < curve.xs)
					break;
			}
			Y0 = (curve.ye - curve.Y_Central) + (Curve_buff[curve.channel][num % 1024] - curve.VD_Central) * curve.MUL_Y / 256;
			Y1 = (curve.ye - curve.Y_Central) + (Curve_buff[curve.channel][(num - 1) % 1024] - curve.VD_Central) * curve.MUL_Y / 256;

			if (Y0 < curve.ys)
				Y0 = curve.ys; // When the Y coordinate exceeds the upper or lower limit, it defaults to the upper or lower limit coordinate value
			else if (Y0 > curve.ye - curve.Width + 1)
				Y0 = curve.ye - curve.Width + 1; // Keep the part with lineweight greater than 1, so the Y coordinate value should be offset (lineweight - 1) pixels
			if (Y1 < curve.ys)
				Y1 = curve.ys;
			else if (Y1 > curve.ye - curve.Width + 1)
				Y1 = curve.ye - curve.Width + 1;
		}
		else if (Screen_DIR == 3)
		{
			Y0 = y;
			if (curve.dir == 0)
			{
				Y1 = y + curve.Dis_HOR;
				if (Y1 + (curve.Width - 1) > curve.ye)
					break;
			}
			else
			{
				Y1 = y - curve.Dis_HOR;
				if (Y1 < curve.ys)
					break;
			}

			X0 = yCentral - Curve_buff[curve.channel][num % 1024] * curve.MUL_Y / 256;
			X1 = yCentral - Curve_buff[curve.channel][(num - 1) % 1024] * curve.MUL_Y / 256;

			if (X0 < curve.xs)
				X0 = curve.xs;
			else if (X0 > curve.xe - curve.Width + 1)
				X0 = curve.xe - curve.Width + 1;
			if (X1 < curve.xs)
				X1 = curve.xs;
			else if (X1 > curve.xe - curve.Width + 1)
				X1 = curve.xe - curve.Width + 1;
		}
        if (pic_update == 0)
			LT268_TFT_DrawLine_Width_Buffer(X0 - curve.xs, Y0 - curve.ys,
											X1 - curve.xs, Y1 - curve.ys,
											curve.color, curve.Width, buff_w);
		 else
		 {
			LT268_TFT_DrawLine_Width_Buffer(X0, Y0,
											X1, Y1,
											curve.color, curve.Width, FullScreen_w);
		 }

        if (Screen_DIR == 0)
		{
			if (curve.dir == 0)
				x = x - curve.Dis_HOR;
			else
				x = x + curve.Dis_HOR;
		}
		else if (Screen_DIR == 1)
		{
			if (curve.dir == 0)
				y = y - curve.Dis_HOR;
			else
				y = y + curve.Dis_HOR;
		}
		else if (Screen_DIR == 2)
		{
			if (curve.dir == 0)
				x = x + curve.Dis_HOR;
			else
				x = x - curve.Dis_HOR;
		}
		else if (Screen_DIR == 3)
		{
			if (curve.dir == 0)
				y = y + curve.Dis_HOR;
			else
				y = y - curve.Dis_HOR;
		}

        num--;
    }

    // display
    if (pic_update == 0)
    	LT268_buffer_to_TFT(0, 0, buff_w, m_PngData,curve.xs, curve.ys, buff_w, buff_h);

}

/***********************************************************************************
 * Function Name : Real_time_curve_display_dynamic
 * Description   : Show Dynamic Curves.
 * Input         : - group: which group of curve
 * Output        : None
 * Return        : None
 ************************************************************************************/
void Real_time_curve_display_dynamic(uint8_t group)
{
    uint8_t temp = 0, once_flag = 0;
    uint16_t points = 0, num = 0, yCentral = 0, x, y, i = 0, j = 0;
    int16_t X0 = 0, X1 = 0, Y0 = 0, Y1 = 0;
    uint16_t buff_w = 0, buff_h = 0;

    for (i = 0; i < curve_num; i++)
    {
        if (gCurve_Info[i].group == group)
        {
            // Only load the background once under the same group
            if (once_flag == 0)
            {
                buff_w = gCurve_Info[i].xe - gCurve_Info[i].xs + 1;
                buff_h = gCurve_Info[i].ye - gCurve_Info[i].ys + 1;

                // full_screen background

                LT268_BG_to_buffer(0, 0, buff_w, m_PngData,
                                    gCurve_Info[i].xs, gCurve_Info[i].ys, buff_w, buff_h);

                temp = i;
                once_flag = 1;
            }
			if (Screen_DIR == 0)
			{
				if (gCurve_Info[i].dir == 0)
				{
					x = gCurve_Info[i].xe - (gCurve_Info[i].Width - 1);
					points = (x - gCurve_Info[i].xs + 1) / gCurve_Info[i].Dis_HOR;
				}
				else
				{
					x = gCurve_Info[i].xs;
					points = (gCurve_Info[i].xe - x + 1) / gCurve_Info[i].Dis_HOR;
				}
				 yCentral = (gCurve_Info[i].ys + gCurve_Info[i].Y_Central) + gCurve_Info[i].VD_Central * gCurve_Info[i].MUL_Y / 256;
			}
			else if (Screen_DIR == 1)
			{
				if (gCurve_Info[i].dir == 0)
				{
					y = gCurve_Info[i].ye - (gCurve_Info[i].Width - 1);
					points = (y - gCurve_Info[i].ys + 1) / gCurve_Info[i].Dis_HOR;
				}
				else
				{
					y = gCurve_Info[i].ys;
					points = (gCurve_Info[i].ye - y + 1) / gCurve_Info[i].Dis_HOR;
				}
			}
            else if (Screen_DIR == 2)
			{
				if (gCurve_Info[i].dir == 0)
				{
					x = gCurve_Info[i].xs;
					points = (gCurve_Info[i].xe - x + 1) / gCurve_Info[i].Dis_HOR;
				}
				else
				{
					x = gCurve_Info[i].xe - (gCurve_Info[i].Width - 1);
					points = (x - gCurve_Info[i].xs + 1) / gCurve_Info[i].Dis_HOR;
				}
			}
			else if (Screen_DIR == 3)
			{
				if (gCurve_Info[i].dir == 0)
				{
					y = gCurve_Info[i].ys;
					points = (gCurve_Info[i].ye - y + 1) / gCurve_Info[i].Dis_HOR;
				}
				else
				{
					y = gCurve_Info[i].ye - (gCurve_Info[i].Width - 1);
					points = (y - gCurve_Info[i].ys + 1) / gCurve_Info[i].Dis_HOR;
				}
				yCentral = (gCurve_Info[i].xs + gCurve_Info[i].Y_Central) + gCurve_Info[i].VD_Central * gCurve_Info[i].MUL_Y / 256;
			}

            num = Curve_count[gCurve_Info[i].channel] - 1 + 1024;

            for (j = 0; j < points; j++)
            {
				if (Screen_DIR == 0)
				{
					X0 = x;
					if (gCurve_Info[i].dir == 0)
					{
						X1 = x - gCurve_Info[i].Dis_HOR;
						if (X1 < gCurve_Info[i].xs)
							break;
					}
					else
					{
						X1 = x + gCurve_Info[i].Dis_HOR;
						if (X1 + (gCurve_Info[i].Width - 1) > gCurve_Info[i].xe)
							break;
					}
					Y0 = yCentral - Curve_buff[gCurve_Info[i].channel][num % 1024] * gCurve_Info[i].MUL_Y / 256;
					Y1 = yCentral - Curve_buff[gCurve_Info[i].channel][(num - 1) % 1024] * gCurve_Info[i].MUL_Y / 256;

					if (Y0 < gCurve_Info[i].ys)
						Y0 = gCurve_Info[i].ys;
					else if (Y0 > gCurve_Info[i].ye - gCurve_Info[i].Width + 1)
						Y0 = gCurve_Info[i].ye - gCurve_Info[i].Width + 1;
					if (Y1 < gCurve_Info[i].ys)
						Y1 = gCurve_Info[i].ys;
					else if (Y1 > gCurve_Info[i].ye - gCurve_Info[i].Width + 1)
						Y1 = gCurve_Info[i].ye - gCurve_Info[i].Width + 1;
				}
				else if (Screen_DIR == 1)
				{
					Y0 = y;

					if (gCurve_Info[i].dir == 0)
					{
						Y1 = y - gCurve_Info[i].Dis_HOR;
						if (Y1 < gCurve_Info[i].ys)
							break;
					}
					else
					{
						Y1 = y + gCurve_Info[i].Dis_HOR;
						if (Y1 + (gCurve_Info[i].Width - 1) > gCurve_Info[i].ye)
							break;
					}

					X0 = (gCurve_Info[i].xe - gCurve_Info[i].Y_Central) + (Curve_buff[gCurve_Info[i].channel][num % 1024] - gCurve_Info[i].VD_Central) * gCurve_Info[i].MUL_Y / 256;
					X1 = (gCurve_Info[i].xe - gCurve_Info[i].Y_Central) + (Curve_buff[gCurve_Info[i].channel][(num - 1) % 1024] - gCurve_Info[i].VD_Central) * gCurve_Info[i].MUL_Y / 256;

					if (X0 < gCurve_Info[i].xs)
						X0 = gCurve_Info[i].xs;
					else if (X0 > gCurve_Info[i].xe - gCurve_Info[i].Width + 1)
						X0 = gCurve_Info[i].xe - gCurve_Info[i].Width + 1;
					if (X1 < gCurve_Info[i].xs)
						X1 = gCurve_Info[i].xs;
					else if (X1 > gCurve_Info[i].xe - gCurve_Info[i].Width + 1)
						X1 = gCurve_Info[i].xe - gCurve_Info[i].Width + 1;
				}
				else if (Screen_DIR == 2)
				{
					X0 = x;
					if (gCurve_Info[i].dir == 0)
					{
						X1 = x + gCurve_Info[i].Dis_HOR;
						if (X1 + (gCurve_Info[i].Width - 1) > gCurve_Info[i].xe)
							break;
					}
					else
					{
						X1 = x - gCurve_Info[i].Dis_HOR;
						if (X1 < gCurve_Info[i].xs)
							break;
					}
					Y0 = (gCurve_Info[i].ye - gCurve_Info[i].Y_Central) + (Curve_buff[gCurve_Info[i].channel][num % 1024] - gCurve_Info[i].VD_Central) * gCurve_Info[i].MUL_Y / 256;
					Y1 = (gCurve_Info[i].ye - gCurve_Info[i].Y_Central) + (Curve_buff[gCurve_Info[i].channel][(num - 1) % 1024] - gCurve_Info[i].VD_Central) * gCurve_Info[i].MUL_Y / 256;

					if (Y0 < gCurve_Info[i].ys)
						Y0 = gCurve_Info[i].ys; // When the Y coordinate exceeds the upper or lower limit, it defaults to the upper or lower limit coordinate value
					else if (Y0 > gCurve_Info[i].ye - gCurve_Info[i].Width + 1)
						Y0 = gCurve_Info[i].ye - gCurve_Info[i].Width + 1; // Keep the part with lineweight greater than 1, so the Y coordinate value should be offset (lineweight - 1) pixels
					if (Y1 < gCurve_Info[i].ys)
						Y1 = gCurve_Info[i].ys;
					else if (Y1 > gCurve_Info[i].ye - gCurve_Info[i].Width + 1)
						Y1 = gCurve_Info[i].ye - gCurve_Info[i].Width + 1;
				}
				else if (Screen_DIR == 3)
				{
					Y0 = y;
					if (gCurve_Info[i].dir == 0)
					{
						Y1 = y + gCurve_Info[i].Dis_HOR;
						if (Y1 + (gCurve_Info[i].Width - 1) > gCurve_Info[i].ye)
							break;
					}
					else
					{
						Y1 = y - gCurve_Info[i].Dis_HOR;
						if (Y1 < gCurve_Info[i].ys)
							break;
					}

					X0 = yCentral - Curve_buff[gCurve_Info[i].channel][num % 1024] * gCurve_Info[i].MUL_Y / 256;
					X1 = yCentral - Curve_buff[gCurve_Info[i].channel][(num - 1) % 1024] * gCurve_Info[i].MUL_Y / 256;

					if (X0 < gCurve_Info[i].xs)
						X0 = gCurve_Info[i].xs;
					else if (X0 > gCurve_Info[i].xe - gCurve_Info[i].Width + 1)
						X0 = gCurve_Info[i].xe - gCurve_Info[i].Width + 1;
					if (X1 < gCurve_Info[i].xs)
						X1 = gCurve_Info[i].xs;
					else if (X1 > gCurve_Info[i].xe - gCurve_Info[i].Width + 1)
						X1 = gCurve_Info[i].xe - gCurve_Info[i].Width + 1;
				}
                LT268_TFT_DrawLine_Width_Buffer(
                            X0 - gCurve_Info[i].xs, Y0 - gCurve_Info[i].ys,
                        X1 - gCurve_Info[i].xs, Y1 - gCurve_Info[i].ys,
                        gCurve_Info[i].color, gCurve_Info[i].Width, buff_w);

				if (Screen_DIR == 0)
				{
					if (gCurve_Info[i].dir == 0)
						x = x - gCurve_Info[i].Dis_HOR;
					else
						x = x + gCurve_Info[i].Dis_HOR;
				}
				else if (Screen_DIR == 1)
				{
					if (gCurve_Info[i].dir == 0)
						y = y - gCurve_Info[i].Dis_HOR;
					else
						y = y + gCurve_Info[i].Dis_HOR;
				}
				else if (Screen_DIR == 2)
				{
					if (gCurve_Info[i].dir == 0)
						x = x + gCurve_Info[i].Dis_HOR;
					else
						x = x - gCurve_Info[i].Dis_HOR;
				}
				else if (Screen_DIR == 3)
				{
					if (gCurve_Info[i].dir == 0)
						y = y + gCurve_Info[i].Dis_HOR;
					else
						y = y - gCurve_Info[i].Dis_HOR;
				}
                num--;
            }
        }
    }

    // display
    LT268_buffer_to_TFT(0, 0, buff_w, m_PngData,
                        gCurve_Info[temp].xs, gCurve_Info[temp].ys, buff_w, buff_h);
}

/***********************************************************************************
* Function Name	: Curve_display
* Description	: Get curves info.
* Input         : - type: curves info sources
                  - buff: curves info
* Output        : None
* Return        : None
************************************************************************************/
void Curve_display(uint8_t type, uint8_t *buff)
{
    uint8_t channel = 0, Dis_HOR = 0, Width = 0, i = 0, count = 0, dir = 0;
    uint16_t p_add, p_len, pointer;
    uint16_t xs = 0, ys = 0, xe = 0, ye = 0, Y_Central = 0, VD_Central = 0, MUL_Y = 0;
    uint32_t color = 0;

    if (type == 0)		// Instruction information source is configuration file
    {
        xs = buff[5] + (buff[6] << 8);
        ys = buff[7] + (buff[8] << 8);
        xe = buff[9] + (buff[10] << 8);
        ye = buff[11] + (buff[12] << 8);
        Y_Central = buff[13] + (buff[14] << 8);
        VD_Central = buff[15] + (buff[16] << 8);
        MUL_Y = buff[17] + (buff[18] << 8);
        color = buff[19] + (buff[20] << 8) + (buff[21] << 16);
        channel = buff[22] & 0x7F;
        dir = (buff[22] & 0x80) >> 7;
        Dis_HOR = buff[23];
        Width = buff[24];
    }
    else if (type == 1) // Instruction information ource is variable space
    {
		pointer = (buff[2] + (buff[3] << 8)) * 2;
		xs = var[pointer + 1] + (var[pointer + 2] << 8);
		ys = var[pointer + 3] + (var[pointer + 4] << 8);
		xe = var[pointer + 5] + (var[pointer + 6] << 8);
		ye = var[pointer + 7] + (var[pointer + 8] << 8);
		Y_Central = var[pointer + 9] + (var[pointer + 10] << 8);
		VD_Central = var[pointer + 11] + (var[pointer + 12] << 8);
		MUL_Y = var[pointer + 13] + (var[pointer + 14] << 8);
		color = var[pointer + 15] + (var[pointer + 16] << 8) + (var[pointer + 17] << 16);
		channel = var[pointer + 18] & 0x7F;
		dir = (var[pointer + 18] & 0x80) >> 7;
		Dis_HOR = var[pointer + 19];
		Width = var[pointer + 20];
    }

    if (Pop_up_flag == 1) // Popup offset
    {
        xs += Pop_up_x;
        ys += Pop_up_y;
        xe += Pop_up_x;
        ye += Pop_up_y;
    }
    gCurve_Info[curve_num].xs = xs;
    gCurve_Info[curve_num].ys = ys;
    gCurve_Info[curve_num].xe = xe;
    gCurve_Info[curve_num].ye = ye;
    gCurve_Info[curve_num].Y_Central = Y_Central;
    gCurve_Info[curve_num].VD_Central = VD_Central;
    gCurve_Info[curve_num].MUL_Y = MUL_Y;
    gCurve_Info[curve_num].color = color;
    gCurve_Info[curve_num].channel = channel;
    gCurve_Info[curve_num].Dis_HOR = Dis_HOR;
    gCurve_Info[curve_num].Width = Width;
    gCurve_Info[curve_num].dir = dir;

    Real_time_curve_display_static(gCurve_Info[curve_num]);

    curve_update_flag[gCurve_Info[curve_num].channel] = 0;

    // Curve grouping
    if (curve_num)
    {
        for (i = 0; i < curve_num; i++)
        {
            if (gCurve_Info[curve_num].xs != gCurve_Info[i].xs ||
                gCurve_Info[curve_num].ys != gCurve_Info[i].ys ||
                gCurve_Info[curve_num].xe != gCurve_Info[i].xe ||
                gCurve_Info[curve_num].ye != gCurve_Info[i].ye)
            {
            // If x y w h is different, add a group of areas
                count++;
            }
            else
            {
                // If x y w h is the same, it will be classified into the same group of areas
                gCurve_Info[curve_num].group = gCurve_Info[i].group;
                break;
            }
        }
        if (count == curve_num) // Indicates that the latest control is compared with all previous controls. If the area is different, a new group of areas will be added
        {
            curve_group_sum++;
            gCurve_Info[curve_num].group = curve_group_sum;
        }
    }
    else // The first curve control defaults to group 0
    {
        curve_group_sum = 1;
        gCurve_Info[curve_num].group = curve_group_sum;
    }
    curve_num++;
}









